package com.monkeyboy.mytest.util;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.SignatureException;

/**
 * 作用： jwt生成和校验工具类
 * 
 * @author Gavin
 * @time:2019年3月2日
 */
public class TokenUtil {
	/**
	 * 签名的密钥
	 */
	public final static String SIGNINGKEY = "Gavin123@$^&";

	/**
	 * 作用：
	 * 
	 * @Author:Gavin
	 * @time:2019年3月2日
	 * @param payload(json格式字符串的数据，方便解析)
	 * @param seconds(token的过期时间)
	 * @return
	 */
	public static Map<String, Object> getToken(String playload, int seconds) {
		Map<String, Object> res = new HashMap<String, Object>();
		try {
			if (!StringUtils.isBlank(playload)) {
				String token = Jwts.builder().claim("iss", "service")// jwt签发者
						.claim("aud", "client")// jwt接受者
						.claim("playload", playload)// 数据
						.setSubject(playload).setExpiration(getExdate(seconds))// token的过期时间
						.signWith(SignatureAlgorithm.HS512, SIGNINGKEY).compact();
				res.put("status", 200);
				res.put("token", token);
				return res;
			} else {
				res.put("status", 500);
				res.put("msg", "消息体不能为空");
			}
		} catch (Exception e) {
			res.put("status", 500);
			res.put("msg", "系统繁忙，请稍后重试");
		}
		return res;
	}

	/**
	 * 作用： 校验token
	 * 
	 * @Author:Gavin
	 * @time:2019年3月2日
	 * @param token
	 * @return
	 */
	public static Map<String, Object> verifyToken(String token) {
		Map<String, Object> res = new HashMap<String, Object>();
		try {
			if (!StringUtils.isBlank(token)) {
				Jwts.parser().setSigningKey(SIGNINGKEY).parseClaimsJws(token);
				res.put("status", 200);
				res.put("msg", "校验通过。");
				return res;
			} else {
				throw new JwtException("token lost!");
			}
		} catch (ExpiredJwtException e) {
			res.put("status", 500);
			res.put("msg", "身份已过期，重新授权");
		} catch (SignatureException e) {
			res.put("status", 500);
			res.put("msg", "身份校验不通过。");
		} catch (Exception e) {
			e.printStackTrace();
			res.put("status", 500);
			res.put("msg", "身份校验不通过。");
		}
		return res;
	}

	/**
	 * 作用： 获取到token中的消息体
	 * 
	 * @Author:Gavin
	 * @time:2019年3月2日
	 * @param token
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "unused" })
	public static Map<String, Object> getPlayload(String token) {
		Map<String, Object> res = new HashMap<String, Object>();
		try {
			if (Integer.parseInt(String.valueOf(verifyToken(token).get("status"))) == 200) {// 先校验token是否正确
				Jws<Claims> jws = Jwts.parser().setSigningKey(SIGNINGKEY).parseClaimsJws(token);
				String signature = jws.getSignature();// 获取到签名密钥
				Map<String, String> header = jws.getHeader();// 获取到头部信息
				Claims claims = jws.getBody();
				if (!StringUtils.isBlank(String.valueOf(claims.get("playload")))) {
					res.put("playload", claims.get("playload"));
					res.put("status", 200);
					return res;
				} else {
					res.put("status", 500);
					res.put("msg", "token lost");
					return res;
				}
			} else {
				return verifyToken(token);
			}

		} catch (Exception e) {
			res.put("status", 500);
			res.put("msg", "身份校验失败了。");
		}
		return res;
	}

	/**
	 * 作用： 获取一个时间,以秒作为单位
	 * 
	 * @Author:Gavin
	 * @time:2019年3月2日
	 * @param day
	 * @return
	 */
	private static Date getExdate(int seconds) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.SECOND, seconds);
		return calendar.getTime();
	}

	public static void main(String[] args) {
		String token = "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJzZXJ2aWNlIiwiYXVkIjoiY2xpZW50IiwcGxheWxvYWQiOiJ0ZXN0Iiwic3ViIjoidGVzdCIsImV4cCI6MTU1MTUyMTU2MH0.ZNamhJkKl0TEFtpfuh3dKaY7CwRAaGdp3pPa5L2i2QY73_kT0QyTeljVQdsnhYql_JAOMcGed6OLM8AiAg-A0A";
		// System.err.println(getToken("test", 2000));
		// System.out.println(getPlayload(token));
		System.out.println(verifyToken(token));
	}
}
